<template>
  <div id="mapView" class="map-view">
    <!-- 操作面板 -->
    <div class="control-panel">
      <el-card class="control-card">
        <template #header>
          <div class="card-header">
            <h3>新增事故点</h3>
            <p class="subtitle">您可以在地图上标记事故位置并提交信息</p>
            <p class="instruction-text">点击地图上的事故点可以查询和修改</p>
          </div>
        </template>
        <el-button type="primary" @click="startAddAccident" :disabled="isDrawing">
          <el-icon><Plus /></el-icon> 标记事故位置
        </el-button>
        <div class="instruction" v-if="isDrawing">
          <el-alert
            title="请在地图上点击添加事故点位置"
            type="info"
            :closable="false"
            show-icon
          />
        </div>
      </el-card>
    </div>

    <!-- 图层说明提示 -->
    <div class="layer-info-tip">
      <div class="tip-title">图层说明</div>
      <div class="tip-content">
        <div class="tip-item">
          <span class="color-box highway-good"></span> 高速公路 - 良好
        </div>
        <div class="tip-item">
          <span class="color-box highway-normal"></span> 高速公路 - 一般
        </div>
        <div class="tip-item">
          <span class="color-box highway-bad"></span> 高速公路 - 较差
        </div>
        <div class="tip-item">
          <span class="color-box highway-repair"></span> 高速公路 - 维修中
        </div>
        <div class="tip-item">
          <span class="color-box accident"></span> 事故点
        </div>
      </div>
    </div>

    <!-- 事故点属性表单对话框 -->
    <el-dialog
      v-model="accidentFormVisible"
      :title="formMode === 'add' ? '新增事故点' : '编辑事故点'"
      width="500px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
      <el-form
        :model="accidentForm"
        label-width="120px"
        :rules="accidentFormRules"
        ref="accidentFormRef"
      >
        <el-form-item label="事故编号" prop="accident_id" v-if="formMode === 'add'">
          <el-input v-model="accidentForm.accident_id" placeholder="请输入事故编号"></el-input>
        </el-form-item>
        <el-form-item label="事故类型" prop="accident_type">
          <el-select
            v-model="accidentForm.accident_type"
            placeholder="请选择事故类型"
            style="width: 100%"
          >
            <el-option label="追尾" value="追尾"></el-option>
            <el-option label="侧翻" value="侧翻"></el-option>
            <el-option label="碰撞" value="碰撞"></el-option>
            <el-option label="刮蹭" value="刮蹭"></el-option>
            <el-option label="其他" value="其他"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="严重程度" prop="severity">
          <el-select
            v-model="accidentForm.severity"
            placeholder="请选择严重程度"
            style="width: 100%"
          >
            <el-option label="轻微" value="轻微"></el-option>
            <el-option label="一般" value="一般"></el-option>
            <el-option label="严重" value="严重"></el-option>
            <el-option label="特别严重" value="特别严重"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="发生时间" prop="date_time">
          <el-date-picker
            v-model="accidentForm.date_time"
            type="datetime"
            placeholder="选择日期和时间"
            style="width: 100%"
            format="YYYY-MM-DD HH:mm:ss"
            value-format="YYYY-MM-DD HH:mm:ss"
          ></el-date-picker>
        </el-form-item>
        <el-form-item label="所属高速公路" prop="highway_code">
          <el-select
            v-model="accidentForm.highway_code"
            placeholder="请选择所属高速公路"
            style="width: 100%"
          >
            <el-option
              v-for="highway in highwayList"
              :key="highway.attributes.highway_code"
              :label="highway.attributes.highway_name"
              :value="highway.attributes.highway_code"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="位置描述" prop="location_desc">
          <el-input
            v-model="accidentForm.location_desc"
            type="textarea"
            placeholder="请输入位置描述"
          ></el-input>
        </el-form-item>
        <el-form-item label="处理状态" prop="status">
          <el-select v-model="accidentForm.status" placeholder="请选择处理状态" style="width: 100%">
            <el-option label="未处理" value="未处理"></el-option>
            <el-option label="处理中" value="处理中"></el-option>
            <el-option label="已处理" value="已处理"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelAccidentForm">取消</el-button>
          <el-button type="primary" @click="submitAccidentForm">确认</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 事故点详情对话框 -->
    <el-dialog v-model="accidentInfoVisible" title="事故点详情" width="500px">
      <div v-if="selectedAccident" class="accident-info">
        <p><strong>事故编号：</strong>{{ selectedAccident.attributes.accident_id }}</p>
        <p><strong>事故类型：</strong>{{ selectedAccident.attributes.accident_type }}</p>
        <p><strong>严重程度：</strong>{{ selectedAccident.attributes.severity }}</p>
        <p><strong>发生时间：</strong>{{ selectedAccident.attributes.date_time }}</p>
        <p><strong>所属高速公路：</strong>{{ selectedAccident.attributes.highway_code }}</p>
        <p><strong>位置描述：</strong>{{ selectedAccident.attributes.location_desc }}</p>
        <p><strong>处理状态：</strong>{{ selectedAccident.attributes.status }}</p>
        <p v-if="selectedAccident.attributes.HandleMessage">
          <strong>处理信息：</strong>{{ selectedAccident.attributes.HandleMessage }}
        </p>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="accidentInfoVisible = false">关闭</el-button>
          <el-button type="primary" @click="editAccident">编辑</el-button>
          <el-button type="danger" @click="confirmDeleteAccident">删除</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 删除确认对话框 -->
    <el-dialog v-model="deleteConfirmVisible" title="确认删除" width="400px">
      <p>{{ deleteConfirmMessage }}</p>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="deleteConfirmVisible = false">取消</el-button>
          <el-button type="danger" @click="deleteAccident">确认删除</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref, reactive } from 'vue'
import { ElMessage, ElForm } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import Map from '@arcgis/core/Map.js'
import MapView from '@arcgis/core/views/MapView.js'
import FeatureLayer from '@arcgis/core/layers/FeatureLayer.js'
import Graphic from '@arcgis/core/Graphic.js'
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer.js'
import SketchViewModel from '@arcgis/core/widgets/Sketch/SketchViewModel.js'
import SimpleMarkerSymbol from '@arcgis/core/symbols/SimpleMarkerSymbol.js'
import Query from '@arcgis/core/rest/support/Query.js'
import Legend from '@arcgis/core/widgets/Legend.js'
import gaodeLayer from '../utils/GaoDeBaseLayer'

type AccidentFormType = {
  accident_id: string
  accident_type: string
  severity: string
  date_time: string
  highway_code: string
  location_desc: string
  status: string
  HandleMessage?: string
  OBJECTID?: number
}

let view: MapView | null = null
let highwayLayer: FeatureLayer | null = null
let accidentLayer: FeatureLayer | null = null
let sketchLayer: GraphicsLayer | null = null
let sketchViewModel: SketchViewModel | null = null
let tempGraphic: Graphic | null = null

// 状态变量
const isDrawing = ref(false)
const accidentFormVisible = ref(false)
const accidentInfoVisible = ref(false)
const deleteConfirmVisible = ref(false)
const deleteConfirmMessage = ref('')
const formMode = ref<'add' | 'edit'>('add')
const accidentFormRef = ref<InstanceType<typeof ElForm> | null>(null)
let selectedAccident: Graphic | null = null

// 高速公路列表
let highwayList: Graphic[] = []

// 事故点表单数据
const accidentForm = reactive<AccidentFormType>({
  accident_id: '',
  accident_type: '',
  severity: '',
  date_time: '',
  highway_code: '',
  location_desc: '',
  status: '未处理',
  HandleMessage: '',
})

// 事故点表单验证规则
const accidentFormRules = {
  accident_id: [{ required: true, message: '请输入事故编号', trigger: 'blur' }],
  accident_type: [{ required: true, message: '请选择事故类型', trigger: 'change' }],
  severity: [{ required: true, message: '请选择严重程度', trigger: 'change' }],
  date_time: [{ required: true, message: '请选择发生时间', trigger: 'change' }],
  highway_code: [{ required: true, message: '请选择所属高速公路', trigger: 'change' }],
  location_desc: [{ required: true, message: '请输入位置描述', trigger: 'blur' }],
  status: [{ required: true, message: '请选择处理状态', trigger: 'change' }],
}

// 开始添加事故点
const startAddAccident = () => {
  if (!view || !sketchViewModel) return

  isDrawing.value = true
  ElMessage.info('请在地图上点击添加事故点位置')

  // 开始绘制点
  sketchViewModel.create('point')
}

// 取消事故点表单
const cancelAccidentForm = () => {
  accidentFormVisible.value = false
  resetAccidentForm()

  // 清除临时图形
  if (tempGraphic && sketchLayer) {
    sketchLayer.remove(tempGraphic)
    tempGraphic = null
  }

  isDrawing.value = false
}

// 重置事故点表单
const resetAccidentForm = () => {
  if (accidentFormRef.value) {
    accidentFormRef.value.resetFields()
  }

  accidentForm.accident_id = ''
  accidentForm.accident_type = ''
  accidentForm.severity = ''
  accidentForm.date_time = ''
  accidentForm.highway_code = ''
  accidentForm.location_desc = ''
  accidentForm.status = '未处理'
  accidentForm.HandleMessage = ''
  accidentForm.OBJECTID = undefined
}

// 提交事故点表单
const submitAccidentForm = async () => {
  if (!accidentFormRef.value) return

  await accidentFormRef.value.validate(async (valid) => {
    if (valid) {
      if (formMode.value === 'add') {
        // 添加新事故点
        addAccident()
      } else {
        // 更新事故点
        updateAccident()
      }
    }
  })
}

// 生成唯一的事故ID
const generateAccidentId = () => {
  const timestamp = new Date().getTime()
  const random = Math.floor(Math.random() * 1000)
  return `ACC-${timestamp}-${random}`
}

// 添加新事故点
const addAccident = () => {
  if (!tempGraphic || !accidentLayer) return

  // 如果没有输入事故ID，自动生成一个
  if (!accidentForm.accident_id) {
    accidentForm.accident_id = generateAccidentId()
  }

  // 创建新的事故点图形
  const attributes = {
    accident_id: accidentForm.accident_id,
    accident_type: accidentForm.accident_type,
    severity: accidentForm.severity,
    date_time: accidentForm.date_time,
    highway_code: accidentForm.highway_code,
    location_desc: accidentForm.location_desc,
    status: accidentForm.status,
    HandleMessage: accidentForm.HandleMessage || '',
  }

  // 创建新的图形
  const newGraphic = new Graphic({
    geometry: tempGraphic.geometry,
    attributes: attributes,
  })

  // 添加到图层
  accidentLayer
    .applyEdits({
      addFeatures: [newGraphic],
    })
    .then((result) => {
      if (result.addFeatureResults.length > 0) {
        ElMessage.success('事故点添加成功')
        accidentFormVisible.value = false
        resetAccidentForm()

        // 清除临时图形
        if (sketchLayer && tempGraphic) {
          sketchLayer.remove(tempGraphic)
          tempGraphic = null
        }

        isDrawing.value = false
      } else {
        ElMessage.error('事故点添加失败')
      }
    })
    .catch((error) => {
      console.error('添加事故点出错:', error)
      ElMessage.error('事故点添加失败')
    })
}

// 更新事故点
const updateAccident = async () => {
  if (!accidentLayer || !accidentForm.OBJECTID) return

  try {
    // 查询要更新的图形
    const query = new Query()
    query.where = `OBJECTID = ${accidentForm.OBJECTID}`
    query.outFields = ['*']

    const result = await accidentLayer.queryFeatures(query)
    if (result.features.length === 0) {
      ElMessage.error('未找到要更新的事故点')
      return
    }

    // 更新属性
    const updatedGraphic = result.features[0]
    updatedGraphic.attributes.accident_type = accidentForm.accident_type
    updatedGraphic.attributes.severity = accidentForm.severity
    updatedGraphic.attributes.date_time = accidentForm.date_time
    updatedGraphic.attributes.highway_code = accidentForm.highway_code
    updatedGraphic.attributes.location_desc = accidentForm.location_desc
    updatedGraphic.attributes.status = accidentForm.status
    updatedGraphic.attributes.HandleMessage = accidentForm.HandleMessage || ''

    // 提交更新到服务
    const editResult = await accidentLayer.applyEdits({
      updateFeatures: [updatedGraphic],
    })

    if (editResult.updateFeatureResults.length > 0) {
      ElMessage.success('事故点更新成功')
      accidentFormVisible.value = false
      resetAccidentForm()
    } else {
      ElMessage.error('更新事故点失败')
    }
  } catch (error) {
    console.error('更新事故点出错:', error)
    ElMessage.error('更新事故点失败')
  }
}

// 编辑事故点
const editAccident = () => {
  if (!selectedAccident) return

  formMode.value = 'edit'

  // 填充表单数据
  const attrs = selectedAccident.attributes
  accidentForm.accident_id = attrs.accident_id || ''
  accidentForm.accident_type = attrs.accident_type || ''
  accidentForm.severity = attrs.severity || ''
  accidentForm.date_time = attrs.date_time || ''
  accidentForm.highway_code = attrs.highway_code || ''
  accidentForm.location_desc = attrs.location_desc || ''
  accidentForm.status = attrs.status || '未处理'
  accidentForm.HandleMessage = attrs.HandleMessage || ''
  accidentForm.OBJECTID = attrs.OBJECTID

  accidentInfoVisible.value = false
  accidentFormVisible.value = true
}

// 确认删除事故点
const confirmDeleteAccident = () => {
  if (!selectedAccident) return

  deleteConfirmMessage.value = `确定要删除事故编号为 ${selectedAccident.attributes.accident_id} 的事故点吗？`
  accidentInfoVisible.value = false
  deleteConfirmVisible.value = true
}

// 删除事故点
const deleteAccident = async () => {
  if (!selectedAccident || !accidentLayer) return

  try {
    const result = await accidentLayer.applyEdits({
      deleteFeatures: [selectedAccident],
    })

    if (result.deleteFeatureResults.length > 0) {
      ElMessage.success('事故点删除成功')
      selectedAccident = null
    } else {
      ElMessage.error('删除事故点失败')
    }
  } catch (error) {
    console.error('删除事故点出错:', error)
    ElMessage.error('删除事故点失败')
  } finally {
    deleteConfirmVisible.value = false
  }
}

// 加载高速公路列表
const loadHighwayList = async () => {
  if (!highwayLayer) return

  try {
    const query = new Query()
    query.where = '1=1'
    query.outFields = ['highway_code', 'highway_name']
    query.returnGeometry = false

    const result = await highwayLayer.queryFeatures(query)
    highwayList = result.features
  } catch (error) {
    console.error('加载高速公路列表出错:', error)
    ElMessage.error('加载高速公路列表失败')
  }
}

// 初始化地图
const initMap = async () => {
  try {
    const map = new Map({
      basemap: {
        baseLayers: [gaodeLayer],
      },
    })

    view = new MapView({
      container: 'mapView',
      map: map,
      center: [116.404, 39.915], // 北京中心点坐标
      zoom: 10,
    })

    // 创建高速公路图层
    highwayLayer = new FeatureLayer({
      url: 'https://services.arcgis.com/pPin4rPIRy9xhFS0/arcgis/rest/services/HighwayManagemnetSystem/FeatureServer/0',
      outFields: ['*'],
      popupTemplate: {
        title: '{highway_name}',
        content: [
          {
            type: 'fields',
            fieldInfos: [
              { fieldName: 'highway_code', label: '高速公路编号' },
              { fieldName: 'highway_level', label: '高速公路等级' },
              { fieldName: 'lanes', label: '车道数' },
              { fieldName: 'status', label: '路况状态' },
              { fieldName: 'speed_limit', label: '限速(km/h)' }
            ]
          }
        ]
      },
      // 根据status字段设置唯一值渲染
      renderer: {
        type: 'unique-value',
        field: 'status',
        uniqueValueInfos: [
          {
            value: '良好',
            symbol: {
              type: 'simple-line',
              color: '#67C23A',
              width: '3px',
            },
          },
          {
            value: '一般',
            symbol: {
              type: 'simple-line',
              color: '#E6A23C',
              width: '3px',
            },
          },
          {
            value: '较差',
            symbol: {
              type: 'simple-line',
              color: '#F56C6C',
              width: '3px',
            },
          },
          {
            value: '维修中',
            symbol: {
              type: 'simple-line',
              color: '#EE1414',
              width: '3px',
            },
          },
        ],
      },
    })

    // 创建事故点图层
    accidentLayer = new FeatureLayer({
      url: 'https://services.arcgis.com/pPin4rPIRy9xhFS0/arcgis/rest/services/HighwayManagemnetSystem/FeatureServer/1',
      outFields: ['*'],
      popupEnabled: false, // 禁用默认弹出窗口，使用自定义属性面板
      // 设置事故点图层的样式
      renderer: {
        type: 'simple',
        symbol: new SimpleMarkerSymbol({
          style: 'triangle',  // 使用三角形标记
          color: '#E74C3C',  // 红色
          size: 12,
          outline: {
            color: '#C0392B',
            width: 1
          }
        }),
        label: '高速公路事故点'
      }
    })

    // 添加图层到地图
    map.add(highwayLayer)
    map.add(accidentLayer)

    // 创建绘图图层和工具
    sketchLayer = new GraphicsLayer()
    map.add(sketchLayer)

    sketchViewModel = new SketchViewModel({
      view: view,
      layer: sketchLayer,
      pointSymbol: new SimpleMarkerSymbol({
        style: 'triangle',  // 使用三角形标记
        color: '#E74C3C',  // 红色
        size: 12,
        outline: {
          color: '#C0392B',
          width: 1
        }
      }),
    })

    // 添加图例
    const legend = new Legend({
      view: view,
      layerInfos: [
        {
          layer: highwayLayer,
          title: '高速公路'
        },
        {
          layer: accidentLayer,
          title: '事故点'
        }
      ]
    })

    // 将图例添加到右下角
    view.ui.add(legend, 'bottom-right')

    // 监听绘图完成事件
    sketchViewModel.on('create', (event) => {
      if (event.state === 'complete') {
        // 保存临时图形
        tempGraphic = event.graphic

        // 打开表单对话框
        formMode.value = 'add'
        resetAccidentForm()
        accidentFormVisible.value = true
      }
    })

    // 监听点击事件，用于查询事故点
    view.on('click', async (event) => {
      if (isDrawing.value) return

      // 在点击位置查询事故点
      const response = await view.hitTest(event)
      const features = response.results?.filter(
        (result) => result.graphic.layer === accidentLayer
      )

      if (features && features.length > 0) {
        // 显示事故点详情
        selectedAccident = features[0].graphic
        accidentInfoVisible.value = true
      }
    })

    // 加载高速公路列表
    await loadHighwayList()
  } catch (error) {
    console.error('初始化地图出错:', error)
    ElMessage.error('初始化地图失败')
  }
}

onMounted(() => {
  initMap()
})

onUnmounted(() => {
  if (view) {
    view = null
  }
})
</script>

<style scoped>
.map-view {
  width: 100%;
  height: 100%;
  position: relative;
}

.control-panel {
  position: absolute;
  top: 20px;
  left: 20px;
  z-index: 10;
  width: 300px;
}

.control-card {
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 4px;
}

.card-header {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.card-header h3 {
  margin: 0;
  margin-bottom: 5px;
}

.subtitle {
  font-size: 14px;
  color: #666;
  margin: 0;
  margin-bottom: 5px;
}

.instruction-text {
  font-size: 14px;
  color: #e6a23c;
  margin: 5px 0 0 0;
  font-weight: bold;
}

.instruction {
  margin-top: 10px;
}

.accident-info p {
  margin: 8px 0;
}

/* 图层说明提示样式 */
.layer-info-tip {
  position: absolute;
  bottom: 20px;
  right: 20px;
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  padding: 12px;
  z-index: 100;
  max-width: 200px;
  font-size: 12px;
}

.tip-title {
  font-weight: bold;
  margin-bottom: 8px;
  text-align: center;
  border-bottom: 1px solid #ddd;
  padding-bottom: 4px;
}

.tip-content {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tip-item {
  display: flex;
  align-items: center;
  gap: 6px;
}

.color-box {
  width: 16px;
  height: 16px;
  border-radius: 3px;
  display: inline-block;
}

/* 高速公路状态颜色 */
.highway-good {
  background-color: #67C23A;
}

.highway-normal {
  background-color: #E6A23C;
}

.highway-bad {
  background-color: #F56C6C;
}

.highway-repair {
  background-color: #EE1414;
}

/* 点图层颜色 */
.accident {
  background-color: #E74C3C;
}
</style>
